package com.os.opencv.java.chapter9;

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.List;

public class ApproxPolyDP {

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        //读取图像并在屏幕上显示
        Mat src = Imgcodecs.imread("pics/Shapes1.jpg", Imgcodecs.IMREAD_GRAYSCALE);

        Mat binary = new Mat();
        Imgproc.threshold(src, binary, 90, 255, Imgproc.THRESH_BINARY);

        //在屏幕上显示二值图
        HighGui.imshow("binary", binary);
        HighGui.waitKey(0);

        //根据二值图检测轮廓
        List<MatOfPoint> contour = new ArrayList<>();
        Imgproc.findContours(binary, contour, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

        //重新获取色彩图像，用于绘制多边形
        src = Imgcodecs.imread("pics/Shapes1.jpg");

        //参数准备
        Scalar red = new Scalar(0,0,255);
        MatOfPoint2f mop = new MatOfPoint2f();
        MatOfPoint2f dst = new MatOfPoint2f();

        //绘制逼近轮廓的多边形
        for(int i=0; i<contour.size(); i++){
            //将轮廓数据准换为MatOfPoint2f
            contour.get(i).convertTo(mop, CvType.CV_32F);
            //轮廓面积太小的跳过不画
            double area = Imgproc.contourArea(contour.get(i));
            if(area<100)
                continue;
            //获取逼近轮廓的多边形
            Imgproc.approxPolyDP(mop, dst, 4, true);

            //将多边形的数据转换成数组以便于画图
            int row = dst.rows();
            float[] data = new float[row*2];
            dst.get(0,0,data);

            //画多边形的边
            for(int j=0; j<row -1; j++){
                Point pt1 = new Point(data[j*2], data[j*2+1]);
                Point pt2 = new Point(data[j*2+2], data[j*2+3]);
                Imgproc.line(src, pt1, pt2, red, 2);
            }
            //连接多边形第一个和最后一个顶点
            Imgproc.line(src, new Point(data[0], data[1]), new Point(data[row*2-2], data[row*2-1]), red, 2);
        }
        //在屏幕上显示绘有多边形的图像
        HighGui.imshow("approxPolyDP", src);
        HighGui.waitKey(0);

        System.exit(0);
    }
}
